package com.vimi8.ebb.auth.api;

import com.vimi8.ebb.auth.configuration.HttpResponseEntity;
import com.vimi8.ebb.auth.dto.AuthUserDto;
import com.vimi8.ebb.auth.model.Error;
import com.vimi8.ebb.auth.model.LoginUser;
import com.vimi8.ebb.auth.model.QRCode;
import com.vimi8.ebb.auth.model.Token;
import com.vimi8.ebb.auth.service.DBClientDetailsService;
import com.vimi8.ebb.auth.service.UserAuthorityService;
import com.vimi8.ebb.auth.utils.CommonUtil;
import com.vimi8.ebb.auth.utils.TokenConvertUtil;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.*;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.security.oauth2.client.http.OAuth2ErrorHandler;
import org.springframework.security.oauth2.client.resource.BaseOAuth2ProtectedResourceDetails;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;

/**
 * Created by xiehuang on 2016/12/19.
 */
@javax.annotation.Generated(value = "class io.swagger.codegen.languages.SpringCodegen", date = "2016-09-12T05:17:54.080Z")

@RestController
public class QRCodeLoginApiController {
 protected Logger logger = LoggerFactory.getLogger(this.getClass());
@Value("${springfox.documentation.swagger.v2.host}")
private String qrCodeHost;
    private String host="127.0.0.1";
    @Value("${server.contextPath}")
    private String contextPath;
    @Value("${server.port}")
    private String port;
    @Autowired
    private DBClientDetailsService dbClientDetailsService;
    @Autowired
    private UserAuthorityService userAuthorityService;
    @Autowired
    private SimpMessagingTemplate simpMessagingTemplate;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @ApiOperation(value = "生成二维码", notes = "生成二维码.", response = QRCode.class, tags = {"注册登录",})
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "成功,用户信息", response = QRCode.class),
            @ApiResponse(code = 200, message = "失败,返回消息", response = String.class)})
    @RequestMapping(value = "/user/qrcode/path/",
            method = RequestMethod.GET)
    public HttpResponseEntity<QRCode> qrCode(HttpServletRequest request) {
         String sessionId=  request.getSession().getId();
        logger.info("request sessionId="+sessionId);
        QRCode qrCode = new QRCode();
        qrCode.setQrFilePath("http://"+qrCodeHost+"/auth/user/qrcode/?sessionId="+sessionId);
        qrCode.setQrData(sessionId);
        logger.info("qrCode="+qrCode);
        return new HttpResponseEntity<QRCode>(qrCode, HttpStatus.OK);
    }
    @ApiOperation(value = "手机端扫描二维码后缓存sessionId和token", notes = "缓存sessionId和token.", response = QRCode.class, tags = {"注册登录",})
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "成功,用户信息", response = QRCode.class),
            @ApiResponse(code = 200, message = "失败,返回消息", response = String.class)})
    @RequestMapping(value = "/user/qrcode/",
            method = RequestMethod.GET)
    public HttpResponseEntity<String> qrCodeCache(HttpServletRequest request, @ApiParam(value = "客服端扫描时的sessionId", required = true) @RequestParam(value="sessionId",required = true) String sessionId) {
        String token= TokenConvertUtil.obtainToken(request);
        logger.info("request sessionId="+sessionId);
        logger.info("request token="+token);
        try {
            redisTemplate.opsForValue().set(sessionId,token);
        } catch (Exception e) {
            return new HttpResponseEntity<>("cache token error", HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return new HttpResponseEntity<String>("cache token success", HttpStatus.OK);
    }

    @ApiOperation(value = "扫一扫二维码登录", notes = "扫一扫二维码登录.", response = QRCode.class, tags = {"注册登录",})
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "成功,用户信息", response = String.class),
            @ApiResponse(code = 200, message = "失败,返回消息", response = String.class)})
    @MessageMapping("/user/qrcode/login/")
    public String qrCodeLogin(String message, @Header("sessionId") String sessionId) {
        String accessToken= null;
        try {
            accessToken = (String) redisTemplate.opsForValue().get(sessionId);
            //清楚缓存中的sessiontId
            redisTemplate.delete(sessionId);
        } catch (Exception e) {
            logger.info("token from cache error"+e.getMessage());
        }
        logger.info("sessionId="+sessionId);
        logger.info("message="+message);
        logger.info("token="+accessToken);
        JSONObject userJSONObject=TokenConvertUtil.convertToken(accessToken);
        logger.info("userJSONObject="+userJSONObject);
        HttpResponseEntity<String> response=null;
        HttpHeaders responseHttpHeaders=new HttpHeaders();
        responseHttpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
        Error error=new Error().error("invalid_param").errorDescription("param is empty");
        if(StringUtils.isEmpty(userJSONObject)){
            return null;
        }
        String openId= userJSONObject.optString("openid");
        String clientId=userJSONObject.optString("client_id");
        logger.info("openId="+openId+",clientId="+clientId);
        ClientDetails clientDetails =  null;
        try {
            clientDetails = dbClientDetailsService.getClientDetailsByClientId(clientId);
            logger.info("clientDetails-code="+clientDetails);
        } catch (Exception ex) {
            error.error("invalid_param").errorDescription(ex.getLocalizedMessage());
            return null;
        }
        LoginUser loginUser=new LoginUser();
        AuthUserDto authUserDto=userAuthorityService.getAuthUserDtoByOpenid1(openId,clientId);
        logger.info("authUserDto-code="+authUserDto);
        String loginName= StringUtils.isEmpty(authUserDto.getUserName())?(authUserDto.getPhoneNumber()):authUserDto.getUserName();
        logger.info("loginName="+loginName);
        //检查clienid是否有效
        if (clientDetails != null) {
            RestTemplate restTemplate = new RestTemplate();
            restTemplate.setErrorHandler(new OAuth2ErrorHandler(new BaseOAuth2ProtectedResourceDetails()));
            HttpHeaders restHeader = new HttpHeaders();
            restHeader.setContentType(MediaType.APPLICATION_JSON_UTF8);
            restHeader.add("Accept", MediaType.APPLICATION_JSON_UTF8_VALUE);
            restHeader.add("Authorization", "Basic " + CommonUtil.getBASE64(clientDetails.getClientId() + ":" + clientDetails.getClientSecret()));
            String tokenUrl = String.format("/token?grant_type=password&username=%s&password=%s", loginName, authUserDto.getPassword());
            tokenUrl = "http://" + host + ":" + port + contextPath + tokenUrl;
            HttpEntity<Void> formEntity = new HttpEntity<Void>(restHeader);
            Token token = restTemplate.postForObject(tokenUrl, formEntity, Token.class);
            token.setClientId(clientDetails.getClientId());
            logger.info("newToken="+token.getAccess_token());
            simpMessagingTemplate.convertAndSend("/topic/login/notice/"+sessionId, token.getAccess_token());
            return token.getAccess_token();
        }
        return null;
    }

}
